home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / aplictns / cm.1 < prev    next >
Text File  |  1989-11-13  |  43KB  |  1,765 lines

  1. Path: xanth!ukma!tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!uwm.edu!rutgers!texbell!texsun!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i212:  cm - celestial mechanics gravity simulator, Part01/02
  5. Message-ID: <127802@sun.Eng.Sun.COM>
  6. Date: 13 Nov 89 04:24:37 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1754
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: guineau@wjg.enet.dec.com (W. John Guineau)
  12. Posting-number: Volume 89, Issue 212
  13. Archive-name: applications/cm.1
  14.  
  15. CM is a celestial mechanics simulator with an Intuition interface.
  16. You construct a layout of Bodies and specify various parameters
  17. for the bodies and the simulation.  CM then animates the bodies
  18. according to the laws of gravational attraction ( F = Gm1m2/r^2 ).
  19. Setups may be saved to disk to later re-inact interesting scenarios.
  20.  
  21. # This is a shell archive.
  22. # Remove anything above and including the cut line.
  23. # Then run the rest of the file through 'sh'.
  24. # Unpacked files will be owned by you and have default permissions.
  25. #----cut here-----cut here-----cut here-----cut here----#
  26. #!/bin/sh
  27. # shar: SHell ARchive
  28. # Run the following text through 'sh' to create:
  29. #    3body.DAT
  30. #    cm.c
  31. #    cm.doc
  32. # This is archive 1 of a 2-part kit.
  33. # This archive created: Sun Nov 12 20:10:27 1989
  34. echo "extracting 3body.DAT"
  35. sed 's/^X//' << \SHAR_EOF > 3body.DAT
  36. X--- CM Setup Data ---
  37. XG=6.670e+00
  38. Xds=1.000e+00
  39. Xdt=5.000e-01
  40. Xt=0
  41. XTrailLength=-1
  42. XShowTime=1
  43. X--- CM Body Data ---
  44. X#=name ;pen;fixed;Radius;Mass;x,y;Vx,Vy;Dir
  45. X0=SUN ;2;0;0;1.000e+03;3.030e+02,1.910e+02;0.000e+00,0.000e+00;0.000e+00
  46. X1=PLANET1 ;4;0;0;1.000e+01;4.310e+02,1.900e+02;0.000e+00,4.000e+00;9.000e+01
  47. X2=PLANET2 ;6;0;0;1.000e+01;7.900e+01,1.930e+02;0.000e+00,-5.000e+00;2.700e+02
  48. SHAR_EOF
  49. echo "extracting cm.c"
  50. sed 's/^X//' << \SHAR_EOF > cm.c
  51. X/*
  52. X * Celestial Mechanics Simulation Tool
  53. X *
  54. X *    W. John Guineau
  55. X *      3 Royal Crest Drive #9
  56. X *      Marlboro, Mass. 01752
  57. X *      (508) 485-6233
  58. X *
  59. X * Files:
  60. X *        cm.c
  61. X *        cm.h
  62. X *          cm.doc
  63. X *
  64. X * To Compile with Lattice 5.02:
  65. X *
  66. X *        lc -b0 -Lm cm
  67. X *
  68. X *
  69. X *                  NOTICE
  70. X *                  ------ 
  71. X *
  72. X *  I have placed this software in the Public Domain with the
  73. X * condition that all the files remain together and that I remain
  74. X * listed as the original author. This software may not be used for
  75. X * commercial purposes or to make money in any way without expressed
  76. X * written permission from the author (me). I'm including the source
  77. X * code so if you make any significant modifications please concider
  78. X * sending me a copy at the above address. I'd also be interested in
  79. X * any interesting saved setup files you create.
  80. X *
  81. X *
  82. X * This is my first Amiga program so I welcome any comments at all.
  83. X * I wrote this program as both a way to learn the Amiga environment
  84. X * and in response to a conversation I had with a friend on Celestial
  85. X * Mechanics.
  86. X *
  87. X *
  88. X */
  89. X
  90. X#include <stdio.h>
  91. X#include <ctype.h>
  92. X#include <math.h>
  93. X
  94. X#include <exec/types.h>
  95. X#include <exec/ports.h>
  96. X#include <exec/devices.h>
  97. X#include <libraries/dosextens.h>
  98. X#include <intuition/intuition.h>
  99. X#include <intuition/intuitionbase.h>
  100. X#include <graphics/rastport.h>
  101. X#include <graphics/gfxbase.h>
  102. X#include <graphics/gfx.h>
  103. X#include <graphics/display.h>
  104. X#include <graphics/text.h>
  105. X
  106. X
  107. X
  108. X
  109. X#include "cm.h"
  110. X
  111. X
  112. X
  113. X#define NOWAIT 0
  114. X#define WAIT   1
  115. X
  116. X
  117. Xextern struct IntuitionBase *IntuitionBase;
  118. Xextern struct GfxBase *GfxBase;
  119. Xstruct IntuiMessage *message;
  120. X
  121. Xstruct Screen *s;
  122. Xstruct Window *w;
  123. Xstruct Window *pw;
  124. Xstruct RastPort *rp;
  125. Xstruct RastPort *prp;
  126. Xstruct ViewPort *vp;
  127. X
  128. X
  129. X#define ReqNone  0
  130. X#define ReqBody  1
  131. X#define ReqSetup 2
  132. X#define ReqFile  3
  133. X#define ReqAbout 4
  134. X
  135. X
  136. XUBYTE  CancelHit=0;       /* If user selects CANCEL from Reqester */
  137. XUBYTE  ReqActive=ReqNone;  /* Set when a Reqester is active */
  138. X               /*  to keep DoIntuiEvents() from returning */
  139. X               /*  until it gets a REQCLEAR msg */
  140. X
  141. X
  142. Xstruct setup {
  143. X   double   G;
  144. X   double   ds;
  145. X   double   dt;
  146. X   UBYTE    t;
  147. X   WORD     TrailLength;
  148. X   UBYTE    ShowTime;
  149. X} SI;
  150. X
  151. X#define MAXTRAILEN 300
  152. X   
  153. Xstruct Body {            /* Info for a Celestial Body */
  154. X   UBYTE    real;        /* If it's real */
  155. X   UBYTE    fixed;        /* Body fixed in place */
  156. X   UBYTE    pen;            /* Color Register */
  157. X   char     name[10];        /* user given name */
  158. X   ULONG    Radius;        /* radius */
  159. X   double   Mass;        /* mass */
  160. X   double   x,y;        /* current position */
  161. X   double   Vx,Vy;        /* velocity components */
  162. X   double   Fx,Fy;        /* resultant force components */
  163. X   double   Dir;        /* direction angle (radians) */
  164. X   double   TrailX[MAXTRAILEN]; /* X of trail of pixels to clear */
  165. X   double   TrailY[MAXTRAILEN]; /* X of trail of pixels to clear */
  166. X   WORD     TrailIDX;
  167. X};
  168. X
  169. X
  170. X#define MAXBODYS 10
  171. Xstruct Body Bodys[MAXBODYS];         /* The array of bodys */
  172. XBYTE   CurBody,TotalBodys=0;
  173. X
  174. XULONG    Et;                /* elapsed time */
  175. X
  176. X
  177. X#define MODE_CREATE 1
  178. X#define MODE_MODIFY 2
  179. X#define MODE_START  3
  180. X#define MODE_STOP   4
  181. XUBYTE    mode = MODE_STOP;        /* Current simulation mode */
  182. X
  183. X
  184. X
  185. X
  186. X/* pointer text for ShowMouse() */
  187. Xchar    pbuf[80];
  188. Xstruct IntuiText pos_txt = {
  189. X   WHTPEN,BLKPEN,            /* FrontPen, BackPen */
  190. X   JAM2,                /* DrawMode */
  191. X   7,2,                  /* LeftEdge, TopEdge */
  192. X   &TxtAt_Plain,            /* TextAttr */
  193. X   pbuf,                /* IText */
  194. X   NULL                 /* NextText */
  195. X};
  196. X
  197. X
  198. X
  199. Xstruct    MsgPort *TimerPort;        /* for Timer stuff */
  200. Xstruct    timerequest *TR;
  201. XUBYTE    TimerOpen=0;
  202. X
  203. X
  204. X
  205. X
  206. X
  207. X/* ============================================================
  208. X *   Main
  209. X *
  210. X * ============================================================*/
  211. X
  212. Xmain(argc,argv)
  213. Xint   argc;
  214. Xchar  *argv[];
  215. X{
  216. X
  217. XOpenStuff();
  218. XInit();
  219. X
  220. XDoIntuiEvents(WAIT);
  221. X
  222. Xreturn(0);
  223. X
  224. X}
  225. X
  226. X
  227. X
  228. X
  229. X
  230. X
  231. X
  232. X
  233. X
  234. XOpenStuff()
  235. X{
  236. X
  237. XTimerPort = (struct MsgPort *)CreatePort(0,0);
  238. Xif(TimerPort == 0) {
  239. X   printf("Cant get a Timer Port\n");
  240. X   CleanUp();
  241. X   exit(10);
  242. X};
  243. X
  244. XTR = (struct timerequest *)CreateExtIO(TimerPort,
  245. X                       sizeof(struct timerequest));
  246. Xif(TR == 0) {
  247. X   printf("Cant get a Timer Request\n");
  248. X   CleanUp();
  249. X   exit(11);
  250. X};
  251. X
  252. X
  253. Xif(OpenDevice(TIMERNAME,UNIT_VBLANK,TR,0) != 0) {
  254. X   printf("Cant open Timer Device\n");
  255. X   CleanUp();
  256. X   exit(12);
  257. X};
  258. XTimerOpen = 1;
  259. X
  260. X
  261. Xif(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))) {
  262. X   printf("no graphics library!!!\n");
  263. X   CleanUp();
  264. X   exit(13);
  265. X};
  266. X
  267. Xif(!(IntuitionBase = (struct IntuitionBase *)
  268. X                  OpenLibrary("intuition.library",0))) {
  269. X   printf("no intuition here!!\n");
  270. X   CleanUp();
  271. X   exit(14);
  272. X};
  273. X
  274. X
  275. X
  276. Xif (!(s = (struct Screen *)OpenScreen(&ns) )) {
  277. X   printf("could not open the screen\n");
  278. X   CleanUp();
  279. X   exit(15);
  280. X};
  281. X
  282. X
  283. X/*
  284. X * set up color map for new screen
  285. X */
  286. Xvp = (struct ViewPort *)&s->ViewPort;
  287. XLoadRGB4(vp,colortable,COLORS);
  288. X
  289. Xnw.Screen = s;         /* point to our screen */
  290. Xnpw.Screen = s;         /* pointer window struct also */
  291. X
  292. Xif (!(w = (struct Window *)OpenWindow(&nw) )) {
  293. X   printf("could not open the window\n");
  294. X   CleanUp();
  295. X   exit(16);
  296. X};
  297. X
  298. Xrp = w->RPort;
  299. XSetAPen(rp,WHTPEN);
  300. X
  301. XSetMenuStrip(w,&Control);
  302. X
  303. Xreturn(0);
  304. X
  305. X}
  306. X
  307. X
  308. X
  309. XInit()
  310. X{
  311. X
  312. XSI.G = 6.67;
  313. XSI.ds = 1.0;
  314. XSI.dt = 1.0;
  315. XSI.t = 0;
  316. XSI.TrailLength = 0;
  317. X
  318. Xcancel_text.IText = cantxt;
  319. X
  320. XOffMenu(w,MN_CStop);
  321. XOffMenu(w,MN_EMod);
  322. XOffMenu(w,MN_FSScr);
  323. X
  324. X
  325. XClearScreen();
  326. XClearBodys();
  327. XSetupGADefaults();
  328. XBodyGADefaults();
  329. X
  330. Xreturn(0);
  331. X
  332. X}
  333. X
  334. X
  335. X
  336. X
  337. XClearScreen()
  338. X{
  339. X
  340. XSetRast(rp,0);
  341. X
  342. XSetAPen(rp,WHTPEN);
  343. X
  344. Xreturn(0);
  345. X
  346. X}
  347. X
  348. X
  349. XDoIntuiEvents(wait)
  350. XUBYTE wait;
  351. X{
  352. XULONG  MessageClass;
  353. XUSHORT code,qual;
  354. Xstruct Gadget *GAD;
  355. Xstruct MsgPort *mp;
  356. X
  357. Xmp = w->UserPort;
  358. X
  359. Xfor(;;) {
  360. X
  361. X   if(message = (struct IntuiMessage *)GetMsg(w->UserPort)) {
  362. X
  363. X      MessageClass = message->Class;
  364. X      code = message->Code;
  365. X      qual = message->Qualifier;
  366. X      GAD = (struct Gadget *)message->IAddress;
  367. X
  368. X      ReplyMsg(message);
  369. X
  370. X      switch (MessageClass) {
  371. X
  372. X     case GADGETUP      : DoGadget(GAD);
  373. X                break;
  374. X
  375. X     case MENUPICK    : if(code != MENUNULL) {
  376. X                               DoMenu(code);
  377. X                            };
  378. X                            break;
  379. X
  380. X     case CLOSEWINDOW : CleanUp();
  381. X                exit(0);
  382. X                break;
  383. X
  384. X     case MOUSEBUTTONS: if(code == SELECTDOWN) {
  385. X                   MakeBody(w->GZZMouseX,w->GZZMouseY);
  386. X                };
  387. X                break;
  388. X
  389. X     case MOUSEMOVE   : if(mode == MODE_CREATE) {
  390. X                   ShowMouse(w->GZZMouseX,w->GZZMouseY);
  391. X                };
  392. X                break;
  393. X
  394. X     case REQCLEAR      : 
  395. X                ReqActive = ReqNone;
  396. X                break;
  397. X
  398. X     default      : 
  399. X                break;
  400. X
  401. X      };
  402. X
  403. X   } else {
  404. X
  405. X      if(!wait&&!ReqActive) return(0);
  406. X
  407. X      WaitPort(mp);
  408. X
  409. X   };
  410. X
  411. X};
  412. Xreturn(0);
  413. X}
  414. X
  415. X
  416. X
  417. XDoGadget(GAD)
  418. Xstruct    Gadget *GAD;
  419. X{
  420. XULONG    val;
  421. Xstruct    StringInfo *info;
  422. X
  423. X
  424. Xinfo = (struct StringInfo *)GAD->SpecialInfo;
  425. Xval  = info->LongInt;
  426. X
  427. Xswitch(GAD->GadgetID) {
  428. X
  429. X   case NAMEGAD        : 
  430. X                          ActivateGadget(&mass,w,&BodyInfo);
  431. X                          break;
  432. X   case RADIUSGAD       : 
  433. X                          break;
  434. X
  435. X   case MASSGAD         : 
  436. X                          ActivateGadget(&velocity,w,&BodyInfo);
  437. X                          break;
  438. X
  439. X   case VELOCITYGAD     : 
  440. X                          ActivateGadget(&direction,w,&BodyInfo);
  441. X                          break;
  442. X
  443. X   case DIRECTIONGAD    : 
  444. X                          break;
  445. X
  446. X   case OKGAD        : 
  447. X              CancelHit=0;
  448. X                          if(pw)
  449. X                             WindowToFront(pw);
  450. X              break;
  451. X
  452. X   case CANCELGAD    : 
  453. X              CancelHit=1;
  454. X                          if(pw)
  455. X                             WindowToFront(pw);
  456. X              break;
  457. X
  458. X   case RESETGAD        : 
  459. X                          switch(ReqActive) {
  460. X                             case ReqBody  : BodyGADefaults();
  461. X                                             RefreshGadgets(&mass,
  462. X                                                            w,&BodyInfo);
  463. X                                             break;
  464. X                             case ReqSetup : SetupGADefaults();
  465. X                                             RefreshGadgets(&dt,
  466. X                                                            w,&SetupInfo);
  467. X                                             break;
  468. X                            
  469. X                          };
  470. X                          break;
  471. X
  472. X   case GGAD            : 
  473. X                          ActivateGadget(&dt,w,&SetupInfo);
  474. X                          break;
  475. X
  476. X   case DTGAD           : 
  477. X                          ActivateGadget(&t,w,&SetupInfo);
  478. X                          break;
  479. X
  480. X   case TGAD            : 
  481. X                          ActivateGadget(&ds,w,&SetupInfo);
  482. X                          break;
  483. X
  484. X   case DSGAD           : 
  485. X                          ActivateGadget(&tl,w,&SetupInfo);
  486. X                          break;
  487. X
  488. X   case TLGAD           : 
  489. X                          break;
  490. X
  491. X   case COLOR1GAD    : 
  492. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  493. X                          break;
  494. X   case COLOR2GAD    : 
  495. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  496. X                          break;
  497. X   case COLOR3GAD    : 
  498. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  499. X                          break;
  500. X   case COLOR4GAD    : 
  501. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  502. X                          break;
  503. X   case COLOR5GAD    : 
  504. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  505. X                          break;
  506. X   case COLOR6GAD    : 
  507. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  508. X                          break;
  509. X   case COLOR7GAD    : 
  510. X                          Bodys[CurBody].pen = (UBYTE)GAD->UserData;
  511. X                          break;
  512. X   case FNOKGAD        : 
  513. X                          CancelHit=0;
  514. X                          break;
  515. X   case FNCANGAD    : 
  516. X                          CancelHit=1;
  517. X                          break;
  518. X   case STGAD        : if(st.Flags&SELECTED) {
  519. X                             st.GadgetText = &yes_text;
  520. X                             RefreshGadgets(&st,w,&SetupInfo);
  521. X                             SI.ShowTime=1;
  522. X                          } else {
  523. X                             st.GadgetText = &no_text;
  524. X                             RefreshGadgets(&st,w,&SetupInfo);
  525. X                             SI.ShowTime=0;
  526. X                          };
  527. X                          break;
  528. X   case FXGAD        : if(fixed.Flags&SELECTED) {
  529. X                             fixed.GadgetText = &yes_text;
  530. X                             RefreshGadgets(&fixed,w,&BodyInfo);
  531. X                             Bodys[CurBody].fixed=1;
  532. X                          } else {
  533. X                             fixed.GadgetText = &no_text;
  534. X                             RefreshGadgets(&fixed,w,&BodyInfo);
  535. X                             Bodys[CurBody].fixed=0;
  536. X                          };
  537. X                          break;
  538. X
  539. X   default        : 
  540. X              break;
  541. X
  542. X};
  543. X
  544. Xreturn(0);
  545. X}
  546. X
  547. X
  548. X
  549. XDoMenu(MN)
  550. XUSHORT MN;
  551. X{
  552. X
  553. Xswitch(MENUNUM(MN)) {
  554. X
  555. X   case M_Control : 
  556. X                    switch(ITEMNUM(MN)) { 
  557. X
  558. X                       case I_Stop    : 
  559. X                                        mode = MODE_STOP;
  560. X                                        ClosePw();
  561. X                            OffMenu(w,MN_CStop);
  562. X                            OnMenu(w,MN_ECreate);
  563. X                            OnMenu(w,MN_ESetup);
  564. X                            OnMenu(w,MN_EMod);
  565. X                            OnMenu(w,MN_EClearS);
  566. X                            OnMenu(w,MN_EClearB);
  567. X                                        OnMenu(w,MN_FSDat);
  568. X                                        OnMenu(w,MN_FLDat);
  569. X                                        OnMenu(w,MN_CStart);
  570. X                                        break;
  571. X                       case I_Start   : 
  572. X                                        if(TotalBodys == 0) {
  573. X                               MSG("No Bodys Created!!","OK","OK");
  574. X                               break;
  575. X                            };
  576. X                            mode = MODE_START;
  577. X                            ModifyIDCMP(w,IDCMPFL);
  578. X                                        if(SI.ShowTime) OpenPw();
  579. X                            OffMenu(w,MN_ECreate);
  580. X                            OffMenu(w,MN_ESetup);
  581. X                            OffMenu(w,MN_EMod);
  582. X                            OffMenu(w,MN_CStart);
  583. X                            OffMenu(w,MN_EClearS);
  584. X                            OffMenu(w,MN_EClearB);
  585. X                                        OffMenu(w,MN_FSDat);
  586. X                                        OffMenu(w,MN_FLDat);
  587. X                                        OnMenu(w,MN_CStop);
  588. X                               DoSimulation();
  589. X                                        break;
  590. X                    };
  591. X                    break;
  592. X
  593. X   case M_Edit    :
  594. X                    switch(ITEMNUM(MN)) {
  595. X
  596. X                       case I_ClearB  : if(MSG("Really Clear Bodys?",
  597. X                                               "YES!","NO!!")) {
  598. X                                           ClearBodys();
  599. X                                           OnMenu(w,MN_FSDat);
  600. X                                           OnMenu(w,MN_FLDat);
  601. X                                        };
  602. X
  603. X                                        break;
  604. X                       case I_ClearS  : 
  605. X                                        ClearScreen();
  606. X                                        break;
  607. X                       case I_Modify  : 
  608. X                                        mode = MODE_MODIFY;
  609. X                                        ModifyBodys();
  610. X                                        break;
  611. X                       case I_Create  : 
  612. X                                        mode = MODE_CREATE;
  613. X                            ModifyIDCMP(w,IDCMPFL_MM);
  614. X                                        OpenPw();
  615. X                            OnMenu(w,MN_CStart);
  616. X                            OnMenu(w,MN_EMod);
  617. X                            OffMenu(w,MN_ECreate);
  618. X                                        OffMenu(w,MN_FLDat);
  619. X                                        cancel_text.IText = cantxt;
  620. X                                        break;
  621. X                       case I_Setup   : 
  622. X                                        Request(&SetupInfo,w);
  623. X                                        Sleep(0L,100000L);
  624. X                                        ActivateGadget(&G,w,&SetupInfo);
  625. X                                        ReqActive = ReqSetup;
  626. X                                        DoIntuiEvents(NOWAIT);
  627. X                                        cancel_text.IText = cantxt;
  628. X                                        if(!CancelHit) GetSetupInfo();
  629. X                                        break;
  630. X                    };
  631. X                    break;
  632. X
  633. X   case M_File    :
  634. X                    switch(ITEMNUM(MN)) {
  635. X
  636. X                       case I_Exit    : 
  637. X                                        CleanUp();
  638. X                                        exit(0);
  639. X                                        break;
  640. X                       case I_SavScr  : 
  641. X                                        break;
  642. X                       case I_SavDat  : 
  643. X                                        DoSaveData();
  644. X                                        break;
  645. X                       case I_LoadDat : 
  646. X                                        DoLoadData();
  647. X                                        break;
  648. X                       case I_About   : 
  649. X                                        Request(&RAbout,w);
  650. X                                        ReqActive = ReqAbout;
  651. X                                        DoIntuiEvents(NOWAIT);
  652. X                                        break;
  653. X                    };
  654. X                    break;
  655. X
  656. X};
  657. X
  658. Xreturn(0);
  659. X
  660. X}
  661. X
  662. X
  663. X
  664. XShowMouse(x,y)
  665. XSHORT x,y;
  666. X{
  667. X
  668. Xif(x<0||y<0) return(0);
  669. X
  670. Xsprintf(pbuf,"  %.3e , %.3e",
  671. X   (double)(x)*SI.ds,(double)(w->GZZHeight-y+1)*SI.ds);
  672. XPrintIText(prp,&pos_txt,0,0);
  673. X
  674. Xreturn(0);
  675. X}
  676. X
  677. XOpenPw()
  678. X{
  679. X
  680. Xif(pw) return(0);
  681. X
  682. Xif (!(pw = (struct Window *)OpenWindow(&npw) )) {
  683. X   printf("could not open the pointer window\n");
  684. X   CleanUp();
  685. X   exit(17);
  686. X};
  687. X
  688. Xprp = pw->RPort;
  689. XSetAPen(prp,BLKPEN);
  690. XSetBPen(prp,WHTPEN);
  691. X
  692. Xreturn(0);
  693. X
  694. X}
  695. X
  696. XClosePw()
  697. X{
  698. Xif(pw) CloseWindow(pw);
  699. Xpw = (struct Window *)NULL;
  700. Xreturn(0);
  701. X}
  702. X
  703. X
  704. X
  705. XGetBodyInfo()
  706. X{
  707. Xdouble V;
  708. X
  709. X
  710. Xstrcpy(Bodys[CurBody].name,name_sbuf);
  711. X
  712. Xif(sscanf(mass_sbuf,"%le",&Bodys[CurBody].Mass) != 1) {
  713. X   MSG("Bad Value for Mass!","OK","OK");
  714. X   return(0);
  715. X};
  716. X
  717. XBodys[CurBody].Dir  =
  718. X   (double)direction_txstr.LongInt * PI/180.0;
  719. X
  720. Xif(sscanf(velocity_sbuf,"%le",&V) != 1) {
  721. X   MSG("Bad Value for Velocity!","OK","OK");
  722. X   return(0);
  723. X};
  724. X
  725. XBodys[CurBody].Vx  =
  726. X   V * cos(Bodys[CurBody].Dir);
  727. XBodys[CurBody].Vy  =
  728. X   V * sin(Bodys[CurBody].Dir);
  729. X
  730. Xif(Bodys[CurBody].pen == 0)
  731. X   Bodys[CurBody].pen = WHTPEN;
  732. X
  733. XBodys[CurBody].Fx  =  0.0;
  734. XBodys[CurBody].Fy  =  0.0;
  735. X
  736. X
  737. Xreturn(0);
  738. X}
  739. X
  740. X
  741. X
  742. X
  743. X
  744. XGetSetupInfo()
  745. X{
  746. XWORD    n;
  747. X
  748. Xif(sscanf(G_sbuf,"%le",&SI.G) != 1) {
  749. X   MSG("Bad Value for G!","OK","OK");
  750. X   return(0);
  751. X};
  752. X
  753. Xif(sscanf(ds_sbuf,"%le",&SI.ds) != 1) {
  754. X   MSG("Bad Value for ds!","OK","OK");
  755. X   return(0);
  756. X};
  757. X
  758. Xif(sscanf(dt_sbuf,"%le",&SI.dt) != 1) {
  759. X   MSG("Bad Value for dt!","OK","OK");
  760. X   return(0);
  761. X};
  762. X
  763. XSI.t  = (UBYTE)t_txstr.LongInt;
  764. X
  765. Xn = (WORD)tl_txstr.LongInt;
  766. Xif(n>MAXTRAILEN) {
  767. X   MSG("TrailLength too large!","OK","OK");
  768. X   return(0);
  769. X};
  770. X
  771. XSI.TrailLength=n;
  772. X
  773. Xreturn(0);
  774. X}
  775. X
  776. X
  777. X
  778. X
  779. XMakeBody(x,y)
  780. XSHORT x,y;
  781. X{
  782. X
  783. X
  784. Xif(mode != MODE_CREATE)
  785. X   return(0);
  786. Xif(x<0 || y<0)
  787. X   return(0);
  788. X
  789. Xif(TotalBodys++ > MAXBODYS) {
  790. X   TotalBodys--;
  791. X   MSG("No More Body's Available!!","OK","OK");
  792. X   return(0);
  793. X};
  794. X
  795. XSetAPen(rp,REDPEN);
  796. XWritePixel(rp,x,y);
  797. XCurBody = FindFreeBody();
  798. Xif(CurBody == -1) {
  799. X   TotalBodys--;
  800. X   MSG("No More Body's Available!!","OK","OK");
  801. X   return(0);
  802. X};
  803. Xcancel_text.IText = cantxt;
  804. X
  805. XBodyGADefaults();
  806. Xsprintf(xy_buf," %.3e , %.3e ",
  807. X   (double)(x)*SI.ds,(double)(w->GZZHeight-y+1)*SI.ds);
  808. XRequest(&BodyInfo,w);
  809. XReqActive = ReqBody;
  810. XSleep(0L,100000L);
  811. XActivateGadget(&name,w,&BodyInfo);
  812. XDoIntuiEvents(NOWAIT);
  813. X
  814. Xif(CancelHit) {
  815. X   TotalBodys--;
  816. X   SetAPen(rp,BLKPEN);
  817. X   WritePixel(rp,x,y);
  818. X   return(0);
  819. X};
  820. X
  821. XGetBodyInfo();
  822. X
  823. Xif(Bodys[CurBody].Mass == 0.0) {
  824. X   TotalBodys--;
  825. X   SetAPen(rp,BLKPEN);
  826. X   WritePixel(rp,x,y);
  827. X   MSG("Mass can't be ZERO!!","OK","OK");
  828. X   return(0);
  829. X};
  830. X
  831. XBodys[CurBody].x = (double)(x)*SI.ds;
  832. XBodys[CurBody].y = (double)(y)*SI.ds;
  833. XBodys[CurBody].real = 1;
  834. XSetAPen(rp,Bodys[CurBody].pen);
  835. XWritePixel(rp,x,y);
  836. X
  837. Xreturn(0);
  838. X
  839. X}
  840. X
  841. XFindFreeBody()
  842. X{
  843. Xint    x;
  844. X
  845. Xfor(x=0 ; x<MAXBODYS ; x++)
  846. X   if(!Bodys[x].real) return(x);
  847. X
  848. Xreturn(-1);
  849. X
  850. X}
  851. X
  852. X
  853. XModifyBodys()
  854. X{
  855. Xint     n;
  856. XSHORT    x,y;
  857. X
  858. X
  859. Xmode = MODE_MODIFY;
  860. XModifyIDCMP(w,IDCMPFL);
  861. XClosePw();
  862. XOffMenu(w,MN_CStart);
  863. XOffMenu(w,MN_EMod);
  864. XOffMenu(w,MN_ECreate);
  865. Xcancel_text.IText = deltxt;
  866. X
  867. X
  868. Xfor(n=0 ; n<MAXBODYS ; n++) {
  869. X
  870. X   CurBody = n;
  871. X   if(Bodys[n].real) {
  872. X
  873. X      Bodys[n].real=0;
  874. X
  875. X      LoadBodyReq(n);
  876. X      x = (SHORT)(Bodys[n].x/SI.ds);
  877. X      y = (SHORT)(Bodys[n].y/SI.ds);
  878. X
  879. X      color_text.FrontPen = Bodys[n].pen;
  880. X      sprintf(xy_buf," %.3e , %.3e ",
  881. X              (double)(x)*SI.ds,(double)(w->GZZHeight-y+1)*SI.ds);
  882. X      Request(&BodyInfo,w);
  883. X      Sleep(0L,100000L);
  884. X      ReqActive = ReqBody;
  885. X      ActivateGadget(&name,w,&BodyInfo);
  886. X      DoIntuiEvents(NOWAIT);
  887. X   
  888. X      if(CancelHit) {        /* GAD really says "DELETE" */
  889. X         TotalBodys--;
  890. X         SetAPen(rp,BLKPEN);
  891. X         WritePixel(rp,x,y);
  892. X         continue;
  893. X      };
  894. X   
  895. X      GetBodyInfo();
  896. X   
  897. X      if(Bodys[n].Mass == 0.0) {
  898. X         TotalBodys--;
  899. X         SetAPen(rp,BLKPEN);
  900. X         WritePixel(rp,(SHORT)x,(SHORT)y);
  901. X         MSG("Mass can't be ZERO!!","OK","OK");
  902. X         continue;
  903. X      };
  904. X   
  905. X      Bodys[n].real=1;
  906. X      SetAPen(rp,Bodys[CurBody].pen);
  907. X      WritePixel(rp,x,y);
  908. X
  909. X   };
  910. X};
  911. X
  912. X
  913. Xcolor_text.FrontPen = WHTPEN;
  914. X
  915. XOnMenu(w,MN_CStart);
  916. XOnMenu(w,MN_ECreate);
  917. Xif(TotalBodys)
  918. X   OnMenu(w,MN_EMod);
  919. Xelse
  920. X   OffMenu(w,MN_EMod);
  921. X
  922. Xreturn(0);
  923. X
  924. X}
  925. X
  926. X
  927. X
  928. XLoadBodyReq(n)
  929. Xint    n;
  930. X{
  931. Xdouble    v;
  932. X
  933. Xname_txstr.NumChars = sprintf(name_sbuf,"%s",Bodys[n].name);
  934. Xmass_txstr.NumChars = sprintf(mass_sbuf,"%.3e",Bodys[n].Mass);
  935. X
  936. Xdirection_txstr.LongInt = (ULONG)(Bodys[n].Dir * 180.0/PI);
  937. Xdirection_txstr.NumChars = sprintf(direction_sbuf,"%ld",
  938. X                                   direction_txstr.LongInt);
  939. X
  940. Xv = Bodys[n].Vx*Bodys[n].Vx + Bodys[n].Vy*Bodys[n].Vy;
  941. Xv = sqrt(v);
  942. Xvelocity_txstr.NumChars = sprintf(velocity_sbuf,"%.3e",v);
  943. X
  944. Xif(Bodys[n].fixed) {
  945. X   fixed.GadgetText = &yes_text;
  946. X   fixed.Flags |= SELECTED;
  947. X} else {
  948. X   fixed.GadgetText = &no_text;
  949. X   fixed.Flags &= ~SELECTED;
  950. X}
  951. X
  952. Xreturn(0);
  953. X}
  954. X
  955. X
  956. X
  957. X
  958. XDoSimulation()
  959. X{
  960. XUBYTE b;
  961. Xdouble     F,Fx=0.0,Fy=0.0,V;
  962. X
  963. X
  964. XEt = 0L;
  965. X
  966. Xwhile(mode == MODE_START) {
  967. X
  968. X if(SI.ShowTime) {
  969. X   sprintf(pbuf," Time  %ld",Et);
  970. X   PrintIText(prp,&pos_txt,0,0);
  971. X };
  972. X
  973. X /*
  974. X  * Calculate new directions & velocities
  975. X  * resulting from all external forces (all other bodies)
  976. X  */
  977. X
  978. X for(b=0 ; b<MAXBODYS ; b++ ) {
  979. X
  980. X   if(!Bodys[b].real) continue;
  981. X   if(Bodys[b].fixed) continue;
  982. X
  983. X   GetForces(b,&Fx,&Fy);
  984. X
  985. X   if(Fx != 0.0 && Fy != 0.0) {
  986. X
  987. X      F = sqrt(Fx*Fx+Fy*Fy);           /* Total force on this body */
  988. X                       /*  indirection of A */
  989. X      V = F*SI.dt/Bodys[b].Mass;       /* FT = MV (impulse) */
  990. X
  991. X      Bodys[b].Vx += V*Fx/F; /* Fx/F = cos(A). adj vel as a result of impulse */
  992. X      Bodys[b].Vy += V*Fy/F; /* Fy/F = sin(A).  in direction of resultant Force */
  993. X
  994. X      Bodys[b].Dir = atan2(Bodys[b].Vy,Bodys[b].Vx);  /* new direction */
  995. X      if(Bodys[b].Dir < 0.0)
  996. X     Bodys[b].Dir += 2.0*PI;
  997. X   };
  998. X
  999. X
  1000. X };
  1001. X
  1002. X /*
  1003. X  * Display new positions
  1004. X  */
  1005. X
  1006. X for(b=0 ; b<MAXBODYS ; b++) {
  1007. X
  1008. X   if(!Bodys[b].real) continue;
  1009. X
  1010. X   if(!SI.TrailLength) {
  1011. X      SetAPen(rp,BLKPEN);
  1012. X      WritePixel(rp,(SHORT)(Bodys[b].x/SI.ds),(SHORT)(Bodys[b].y/SI.ds));
  1013. X   } else {
  1014. X      if(SI.TrailLength>0) {
  1015. X         if(Bodys[b].TrailIDX >= SI.TrailLength)
  1016. X            Bodys[b].TrailIDX=0;
  1017. X         if(Bodys[b].TrailX[Bodys[b].TrailIDX]>=0) {
  1018. X            SetAPen(rp,BLKPEN);
  1019. X            WritePixel(rp,(SHORT)(Bodys[b].TrailX[Bodys[b].TrailIDX]/SI.ds),
  1020. X                          (SHORT)(Bodys[b].TrailY[Bodys[b].TrailIDX]/SI.ds));
  1021. X            
  1022. X         };
  1023. X         Bodys[b].TrailX[Bodys[b].TrailIDX] = Bodys[b].x;
  1024. X         Bodys[b].TrailY[Bodys[b].TrailIDX] = Bodys[b].y;
  1025. X         Bodys[b].TrailIDX++;
  1026. X      };
  1027. X   };
  1028. X
  1029. X   Bodys[b].x += (Bodys[b].Vx * SI.dt);
  1030. X   Bodys[b].y -= (Bodys[b].Vy * SI.dt);
  1031. X
  1032. X   SetAPen(rp,Bodys[b].pen);
  1033. X   WritePixel(rp,(SHORT)(Bodys[b].x/SI.ds),(SHORT)(Bodys[b].y/SI.ds));
  1034. X
  1035. X };
  1036. X
  1037. XDoIntuiEvents(NOWAIT);
  1038. X
  1039. Xif(SI.t)
  1040. X   Sleep(0L,(ULONG)SI.t*1000L);
  1041. X
  1042. XEt++;
  1043. X
  1044. X};
  1045. X
  1046. Xreturn(0);
  1047. X}
  1048. X
  1049. X
  1050. XGetForces(b,fx,fy)
  1051. XUBYTE b;
  1052. Xdouble *fx,*fy;
  1053. X{
  1054. Xint x;
  1055. Xdouble dY,dX,Fx,Fy,F,R;
  1056. X
  1057. XFx = Fy = 0.0;
  1058. Xfor(x=0 ; x<MAXBODYS ; x++) {
  1059. X
  1060. X   if(x==b) continue;
  1061. X   if(!Bodys[x].real) continue;
  1062. X
  1063. X   dX =  (Bodys[x].x - Bodys[b].x) * SI.ds; /* X2 - X1 */
  1064. X   dY =  (Bodys[b].y - Bodys[x].y) * SI.ds; /* Y2 - Y1 BUT */
  1065. X                         /* normalized to bottom */
  1066. X                         /* left of window */
  1067. X
  1068. X   R = dX*dX+dY*dY;    /* part of sqrt(x^2+y^2) */
  1069. X            /* for F calc below. F needs R^2 so we'll */
  1070. X            /* do sqrt() part after (sqrt(x)^2 = x) */
  1071. X
  1072. X   F =    SI.G * (Bodys[b].Mass * Bodys[x].Mass) / R;
  1073. X
  1074. X   R = sqrt(R);         /* distance between points */
  1075. X
  1076. X   Fx += F*(dX/R);    /* dX/R = cos(A) but faster */
  1077. X   Fy += F*(dY/R);    /* dY/R = sin(A) but faster */
  1078. X
  1079. X};
  1080. X
  1081. X*fx = Fx;
  1082. X*fy = Fy;
  1083. X
  1084. Xreturn(0);
  1085. X}
  1086. X
  1087. X
  1088. XSetupGADefaults()
  1089. X{
  1090. X
  1091. Xstrcpy(G_sbuf,"6.67e0");
  1092. XG_txstr.NumChars=6;
  1093. X
  1094. Xstrcpy(t_sbuf,"0");
  1095. Xt_txstr.NumChars=1;
  1096. Xt_txstr.LongInt = 0L;
  1097. X
  1098. Xstrcpy(ds_sbuf,"1.0e0");
  1099. Xds_txstr.NumChars=5;
  1100. X
  1101. Xstrcpy(dt_sbuf,"1.0e0");
  1102. Xdt_txstr.NumChars=5;
  1103. X
  1104. Xstrcpy(tl_sbuf,"0");
  1105. Xdt_txstr.NumChars=1;
  1106. X
  1107. Xst.GadgetText = &no_text;
  1108. Xst.Flags &= ~SELECTED;
  1109. X
  1110. Xreturn(0);
  1111. X
  1112. X}
  1113. X
  1114. X
  1115. XBodyGADefaults()
  1116. X{
  1117. X
  1118. Xstrcpy(name_sbuf,"SUN");
  1119. Xname_txstr.NumChars=3;
  1120. X
  1121. Xstrcpy(mass_sbuf,"1.0e0");
  1122. Xmass_txstr.NumChars=5;
  1123. X
  1124. Xstrcpy(velocity_sbuf,"0.0e0");
  1125. Xvelocity_txstr.NumChars=5;
  1126. X
  1127. Xstrcpy(direction_sbuf,"0");
  1128. Xdirection_txstr.NumChars=1;
  1129. Xdirection_txstr.LongInt = 0L;
  1130. X
  1131. Xfixed.GadgetText = &no_text;
  1132. Xfixed.Flags &= ~SELECTED;
  1133. X
  1134. Xreturn(0);
  1135. X
  1136. X}
  1137. X
  1138. X
  1139. X
  1140. XClearBodys()
  1141. X{
  1142. Xint    x,t;
  1143. X
  1144. Xfor(x=0 ; x<MAXBODYS ; x++) {
  1145. X   Bodys[x].real = 0;
  1146. X   Bodys[x].pen = 0;
  1147. X
  1148. X   for(t=0 ; t<MAXTRAILEN ; t++) {
  1149. X      Bodys[x].TrailX[t]=-1.0;
  1150. X      Bodys[x].TrailY[t]=-1.0;
  1151. X   };
  1152. X   Bodys[x].TrailIDX = 0;
  1153. X
  1154. X};
  1155. X
  1156. XClearScreen();
  1157. XTotalBodys = 0;
  1158. X
  1159. Xreturn(0);
  1160. X
  1161. X}
  1162. X
  1163. X
  1164. X
  1165. XDoSaveData()
  1166. X{
  1167. Xint    x;
  1168. XFILE    *fp;
  1169. X
  1170. X
  1171. XRequest(&FileName,w);
  1172. XSleep(0L,100000L);
  1173. XActivateGadget(&fn,w,&FileName);
  1174. XReqActive = ReqFile;
  1175. XDoIntuiEvents(NOWAIT);
  1176. X
  1177. Xif(CancelHit)
  1178. X   return(0);
  1179. X
  1180. X
  1181. Xfp = fopen(fn_sbuf,"w");
  1182. Xif(!fp) {
  1183. X   MSG("Can't open output file!","OK!","OH WELL!");
  1184. X   return(0);
  1185. X};
  1186. X
  1187. Xfprintf(fp,"--- CM Setup Data ---\n");
  1188. Xfprintf(fp,"G=%.3e\n",SI.G);
  1189. Xfprintf(fp,"ds=%.3e\n",SI.ds);
  1190. Xfprintf(fp,"dt=%.3e\n",SI.dt);
  1191. Xfprintf(fp,"t=%d\n",(int)SI.t);
  1192. Xfprintf(fp,"TrailLength=%d\n",(int)SI.TrailLength);
  1193. Xfprintf(fp,"ShowTime=%d\n",(int)SI.ShowTime);
  1194. X
  1195. X
  1196. Xfprintf(fp,"--- CM Body Data ---\n");
  1197. Xfprintf(fp,"#=name ;pen;fixed;Radius;Mass;x,y;Vx,Vy;Dir\n");
  1198. Xfor(x=0 ; x<MAXBODYS ; x++)
  1199. X   if(Bodys[x].real) {
  1200. X      fprintf(fp,"%d=%s ;%d;%d;%ld;%.3e;%.3e,%.3e;%.3e,%.3e;%.3e\n",
  1201. X        x,
  1202. X        Bodys[x].name,
  1203. X        (int)Bodys[x].pen,
  1204. X                (int)Bodys[x].fixed,
  1205. X        Bodys[x].Radius,
  1206. X        Bodys[x].Mass,
  1207. X        Bodys[x].x,w->GZZHeight-Bodys[x].y+1,
  1208. X        Bodys[x].Vx,Bodys[x].Vy,
  1209. X        Bodys[x].Dir*180.0/PI);
  1210. X        
  1211. X   };
  1212. X
  1213. Xfclose(fp);
  1214. X
  1215. Xreturn(0);
  1216. X
  1217. X}
  1218. X
  1219. X
  1220. X
  1221. XDoLoadData()
  1222. X{
  1223. Xint    n;
  1224. XFILE    *fp;
  1225. Xchar    buf[101],name[10];
  1226. XULONG    pen,fixed,Radius;
  1227. Xdouble    x,y,Mass,Vx,Vy,Dir;
  1228. X
  1229. X
  1230. XCancelHit=0;
  1231. XRequest(&FileName,w);
  1232. XSleep(0L,100000L);
  1233. XActivateGadget(&fn,w,&FileName);
  1234. XReqActive = ReqFile;
  1235. XDoIntuiEvents(NOWAIT);
  1236. X
  1237. Xif(CancelHit)
  1238. X   return(0);
  1239. X
  1240. X
  1241. Xfp = fopen(fn_sbuf,"r");
  1242. Xif(!fp) {
  1243. X   MSG("Can't open Data File!","OK!","OH WELL!");
  1244. X   return(0);
  1245. X};
  1246. X
  1247. Xfgets(buf,100,fp);    /* forget first line, it's just a header */
  1248. Xfgets(buf,100,fp);
  1249. Xif(sscanf(buf,"G=%le\n",&SI.G) != 1) {
  1250. X   MSG("Bad data file (G)!","OK!","OOPS!");
  1251. X   fclose(fp);
  1252. X   return(0);
  1253. X};
  1254. X
  1255. Xfgets(buf,100,fp);
  1256. Xif(sscanf(buf,"ds=%le\n",&SI.ds) != 1) {
  1257. X   MSG("Bad data file (ds)!","OK!","OOPS!");
  1258. X   fclose(fp);
  1259. X   return(0);
  1260. X};
  1261. X
  1262. Xfgets(buf,100,fp);
  1263. Xif(sscanf(buf,"dt=%le\n",&SI.dt) != 1) {
  1264. X   MSG("Bad data file (dt)!","OK!","OOPS!");
  1265. X   fclose(fp);
  1266. X   return(0);
  1267. X};
  1268. X
  1269. Xfgets(buf,100,fp);
  1270. Xif(sscanf(buf,"t=%d\n",&n) != 1) {
  1271. X   MSG("Bad data file (t)!","OK!","OOPS!");
  1272. X   fclose(fp);
  1273. X   return(0);
  1274. X};
  1275. XSI.t = (UBYTE)n;
  1276. X
  1277. Xfgets(buf,100,fp);
  1278. Xif(sscanf(buf,"TrailLength=%d\n",&n) != 1) {
  1279. X   MSG("Bad data file (TrailLength)!","OK!","OOPS!");
  1280. X   fclose(fp);
  1281. X   return(0);
  1282. X};
  1283. X
  1284. Xif(n>MAXTRAILEN) {
  1285. X   MSG("TrailLength too big","OK!","OOPS!");
  1286. X   fclose(fp);
  1287. X   return(0);
  1288. X};
  1289. XSI.TrailLength = (WORD)n;
  1290. X
  1291. Xfgets(buf,100,fp);
  1292. Xif(sscanf(buf,"ShowTime=%d\n",&n) != 1) {
  1293. X   MSG("Bad data file (ShowTime)!","OK!","OOPS!");
  1294. X   fclose(fp);
  1295. X   return(0);
  1296. X};
  1297. XSI.ShowTime = (WORD)n;
  1298. Xif(n) {
  1299. X   st.GadgetText = &yes_text;
  1300. X   st.Flags |= SELECTED;
  1301. X} else {
  1302. X   st.GadgetText = &no_text;
  1303. X   st.Flags &= ~SELECTED;
  1304. X};   
  1305. X
  1306. X
  1307. XG_txstr.NumChars  = sprintf(G_sbuf,"%.3e",SI.G);
  1308. Xdt_txstr.NumChars = sprintf(dt_sbuf,"%.3e",SI.dt);
  1309. Xt_txstr.NumChars  = sprintf(t_sbuf,"%d",SI.t);
  1310. Xt_txstr.LongInt   = (ULONG)SI.t;
  1311. Xds_txstr.NumChars = sprintf(ds_sbuf,"%.3e",SI.ds);
  1312. Xtl_txstr.LongInt  = (LONG)SI.TrailLength; 
  1313. Xtl_txstr.NumChars = sprintf(tl_sbuf,"%d",SI.TrailLength);
  1314. X
  1315. XClearBodys();
  1316. X
  1317. Xfgets(buf,100,fp);
  1318. Xfgets(buf,100,fp);
  1319. X
  1320. Xwhile(fgets(buf,100,fp) != (char *)NULL) {
  1321. X   if(sscanf(buf,"%d=%s;%d;%d;%ld;%le;%le,%le;%le,%le;%le",
  1322. X             &n,name,&pen,&fixed,&Radius,&Mass,&x,&y,&Vx,&Vy,&Dir) != 11) {
  1323. X      MSG("Bad Body in data file","OK!","OOPS!");
  1324. X      fclose(fp);
  1325. X      return(0);
  1326. X   };
  1327. X   if(n>MAXBODYS) {
  1328. X      MSG("Bad Body # in data file","OK!","OOPS!");
  1329. X      fclose(fp);
  1330. X      return(0);
  1331. X   };
  1332. X
  1333. X   if(!Bodys[n].real) TotalBodys++; /* don't count same definition twice */
  1334. X   Bodys[n].real   = 1;
  1335. X   Bodys[n].pen    = pen;
  1336. X   Bodys[n].fixed  = fixed;
  1337. X   Bodys[n].Radius = Radius; 
  1338. X   Bodys[n].Mass   = Mass;
  1339. X   Bodys[n].x      = x;
  1340. X   Bodys[n].y      = w->GZZHeight-y+1;
  1341. X   Bodys[n].Vx     = Vx;
  1342. X   Bodys[n].Vy     = Vy;
  1343. X   Bodys[n].Dir    = Dir*PI/180.0;
  1344. X   strcpy(Bodys[n].name,name);
  1345. X
  1346. X   SetAPen(rp,pen);
  1347. X   WritePixel(rp,(SHORT)(Bodys[n].x/SI.ds),(SHORT)(Bodys[n].y/SI.ds));
  1348. X        
  1349. X};
  1350. X
  1351. Xfclose(fp);
  1352. X
  1353. XOnMenu(w,MN_ECreate);
  1354. XOnMenu(w,MN_EMod);
  1355. X
  1356. X
  1357. Xreturn(0);
  1358. X
  1359. X}
  1360. X
  1361. X
  1362. XMSG(msg,p,n)
  1363. Xchar    *msg,*p,*n;
  1364. X{
  1365. X
  1366. Xstruct IntuiText msg_txt = {
  1367. X   BLKPEN,REDPEN,            /* FrontPen, BackPen */
  1368. X   JAM1,                /* DrawMode */
  1369. X   10,20,                  /* LeftEdge, TopEdge */
  1370. X   &TxtAt_Plain,            /* TextAttr */
  1371. X   0,                    /* IText */
  1372. X   NULL                 /* NextText */
  1373. X};
  1374. X
  1375. Xstruct IntuiText pos_txt = {
  1376. X   BLKPEN,REDPEN,            /* FrontPen, BackPen */
  1377. X   JAM1,                /* DrawMode */
  1378. X   3,3,                 /* LeftEdge, TopEdge */
  1379. X   &TxtAt_Plain,            /* TextAttr */
  1380. X   0,                    /* IText */
  1381. X   NULL                 /* NextText */
  1382. X};
  1383. X
  1384. Xstruct IntuiText neg_txt = {
  1385. X   BLKPEN,REDPEN,            /* FrontPen, BackPen */
  1386. X   JAM1,                /* DrawMode */
  1387. X   3,3,                 /* LeftEdge, TopEdge */
  1388. X   &TxtAt_Plain,            /* TextAttr */
  1389. X   0,                    /* IText */
  1390. X   NULL                 /* NextText */
  1391. X};
  1392. X
  1393. Xmsg_txt.IText = msg;
  1394. Xpos_txt.IText = p;
  1395. Xneg_txt.IText = n;
  1396. X
  1397. X
  1398. Xreturn(AutoRequest(w,&msg_txt,&pos_txt,&neg_txt,
  1399. X           NULL,NULL,40+IntuiTextLength(&msg_txt),80));
  1400. X
  1401. X}
  1402. X
  1403. X
  1404. X
  1405. X
  1406. X
  1407. X
  1408. XSleep(secs,usecs)
  1409. XULONG    secs,usecs;
  1410. X{
  1411. X
  1412. XTR->tr_node.io_Command = TR_ADDREQUEST;
  1413. XTR->tr_time.tv_secs = secs;
  1414. XTR->tr_time.tv_micro = usecs;
  1415. XDoIO(TR);
  1416. X
  1417. Xreturn(0);
  1418. X
  1419. X}
  1420. X
  1421. X
  1422. X
  1423. X
  1424. X
  1425. XCleanUp()
  1426. X{
  1427. X
  1428. Xif(TimerPort) DeletePort(TimerPort);
  1429. Xif(TimerOpen) CloseDevice(TR);
  1430. Xif(TR) DeleteExtIO(TR,sizeof(struct timerequest));
  1431. Xif(w) {
  1432. X   ClearMenuStrip(w);
  1433. X   CloseWindow(w);
  1434. X};
  1435. Xif(pw) CloseWindow(pw);
  1436. Xif(s) {
  1437. X   CloseScreen(s);
  1438. X/*   FreeColorMap(cm); */
  1439. X};
  1440. Xif(GfxBase) CloseLibrary(GfxBase);
  1441. X(void)OpenWorkBench();
  1442. Xif(IntuitionBase) CloseLibrary(IntuitionBase);
  1443. Xreturn(0);
  1444. X}
  1445. X
  1446. X
  1447. X
  1448. X
  1449. X
  1450. X
  1451. X
  1452. X
  1453. X
  1454. X
  1455. SHAR_EOF
  1456. echo "extracting cm.doc"
  1457. sed 's/^X//' << \SHAR_EOF > cm.doc
  1458. X
  1459. X
  1460. X                CM
  1461. X
  1462. X            Celestial Mechanics Simulator
  1463. X                Version 1.0
  1464. X
  1465. X
  1466. X               W. John Guineau
  1467. X               3 Royal Crest Drive #9
  1468. X            Marlboro, Mass 01752
  1469. X               (508) 485-6233
  1470. X
  1471. X
  1472. X
  1473. X                  NOTICE
  1474. X                  ------
  1475. X
  1476. X  I have placed this software in the Public Domain with the
  1477. Xcondition that all the files remain together and that I remain
  1478. Xlisted as the original author. This software may not be used for
  1479. Xcommercial purposes or to make money in any way without expressed
  1480. Xwritten permission from the author (me). I'm including the source
  1481. Xcode so if you make any significant modifications please concider
  1482. Xsending me a copy at the above address. I'd also be interested in
  1483. Xany interesting saved setup files you create.
  1484. X
  1485. X
  1486. XThis is my first Amiga program so I welcome any comments at all.
  1487. XI wrote this program as both a way to learn the Amiga environment
  1488. Xand in response to a conversation I had with a friend on Celestial
  1489. XMechanics.
  1490. X
  1491. X
  1492. X
  1493. X
  1494. X
  1495. X
  1496. X                What is it?
  1497. X                -----------
  1498. X
  1499. XCM is a Celestial Mechanics simulation tool. It allows you to
  1500. Xconstruct a layout of Masses (called Bodys) and specify various
  1501. Xparameters concerning both the bodys and the simulation. All input
  1502. Xis accomplished through a fully intuitionized interface. CM then
  1503. Xproceeds to animate the bodys according to the laws of gravational
  1504. Xattraction ( F = Gm1m2/r^2 ).  Setups may be saved to disk to allow
  1505. Xyou later re-inact interesting scenarios.
  1506. X
  1507. X
  1508. X
  1509. X
  1510. X              Getting Started
  1511. X              ---------------
  1512. X
  1513. XCM can be run from either the CLI or from workbench by double
  1514. Xclicking it's icon. In order for you to get a quick start, I've
  1515. Xincluded some interesting setup files (described below). Just run
  1516. XCM and select LoadData from the FILE menu. Enter the name of the
  1517. Xsaved simulation you want and hit return (or click OK in the file
  1518. Xrequestor).
  1519. X
  1520. XNext select START from the CONTROL menu. That's it!
  1521. X
  1522. XHere are the included setups:
  1523. X
  1524. X3BODY.DAT - This is a setup of 3 bodys (no kidding!). One is a
  1525. Xvery (relativly) massive body which is not moving. The other two
  1526. Xare much smaller and have initial velocities - one in a close
  1527. Xorbit, the other in a larger orbit. What makes this interesting is
  1528. Xthat on several occasions the two get close enough to affect
  1529. Xeachothers orbit. Then after about t=1400, they swap orbits.
  1530. X
  1531. XFIXED1.DAT - This is an example of a feature in creating bodys
  1532. Xwhere they can be "fixed" in place (i.e. not allowed to move).
  1533. XWhile this is not possible in reality, it makes for some interesting
  1534. Xeffects (and gives a good control on single body experiments).
  1535. X
  1536. XFIXED2.DAT - Another fixed body example. Watch this one around
  1537. Xt=1700!
  1538. X
  1539. X
  1540. XSVEM.DAT - This stands for SUN, VENUS, EARTH, MARS. It's a scale
  1541. Xexperiment of (guess what) the inner planets. While the masses,
  1542. Xvelocities and distances are correct, I don't quite have the
  1543. Xinitial directions just right (although it does indeed take the
  1544. XEarth 365 days to complete an orbit, as well as the other planets
  1545. Xare quite close to thier orbital period). This is a good example for
  1546. Xscaling time and distance.
  1547. X
  1548. XSMVEM.DAT - Another like above. SUN, MERCURY, VENUS, EARTH, MARS.
  1549. X
  1550. X
  1551. X
  1552. X
  1553. X             How to use CM
  1554. X             -------------
  1555. X
  1556. XCM is really pretty easy to use. You first need to decide on what
  1557. Xyou want to simulate. Then decide on an appropriate scale for
  1558. Xboth distance and time.
  1559. X
  1560. XThe visible universe is made up of 635 units in the x direction
  1561. Xand 377 units in the y direction. I say units instead of pixels
  1562. Xbecause CM lets you assign any arbitrary scale to the distance
  1563. Xbetween each pixel. Calculations are based on the scaled distance and on
  1564. Xscaled time. CM lets you specify an arbitrary amount of time for each
  1565. Xiteration of the simulation.
  1566. X
  1567. XThe non-visible universe extends virtually infinetly in all
  1568. Xdirections (2D space).
  1569. X
  1570. XTo see how scaling is useful concider the 3BODY.DAT example
  1571. X(described above). It has a distance scale of 1:1 and a time scale
  1572. Xof 0.5. Which brings up another useful variable to set - G. G is the
  1573. Xgravational constant and is, in reality, equal to 6.67E-11. CM
  1574. Xlets you specify what G is for the calculations. 3BODY.DAT uses
  1575. Xjust 6.67 for G, pretty amazing, huh? :-0.
  1576. X
  1577. XNow contrast 3BODY's settings with those of SVEM.DAT. This is a
  1578. Xreal scale model. The distance scale is 1E6, which just happens
  1579. Xto work nicely for distances in KiloMeters from the SUN to the inner
  1580. Xplanets. The time scale is 8.64E4. What is that?? It's the number of
  1581. Xseconds in one day. G is set to 6.67E-8, which is appropriate
  1582. Xfor the KiloMeter scaling of distance. Since the units for G are
  1583. Xbased on 1 second, time scaling must also be based on 1 second -
  1584. Xhence, 1 day in seconds. This means that for each iteration of the
  1585. Xsimulation, one day goes by and by placing the Earth body 150
  1586. Xunits (pixels) away from the SUN's location, it's really 150E6
  1587. Xkilometers away (it's correct mean distance). Ij addition to
  1588. Xdistance and time, you should use units for Mass and Velocity
  1589. Xthat are consistant with everything. Get the idea?
  1590. X
  1591. X
  1592. XThe best things to do are get a good book with real numbers and
  1593. Xexperiment. Eventually you'll get the feel for the scaling and
  1594. Xhow it affects the simulation.
  1595. X
  1596. X
  1597. X
  1598. X
  1599. X                 The Menus
  1600. X                 ---------
  1601. X
  1602. XWith that simple look at things, heres what the menu's do.
  1603. X
  1604. XThere are 3 main menus in the title bar: FILE, EDIT and CONTROL.
  1605. X
  1606. X
  1607. XThe FILE menu has the following items.
  1608. X
  1609. XABOUT    - Read this one and send mail to the address listed or just
  1610. X      call to say hi! I'd love to hear from anyone using this
  1611. X      program with questions, comments or whatever.
  1612. X
  1613. XLoadData
  1614. X    - This allows you to load in a previously saved setup file.
  1615. X      The files are pretty simple. You can type or edit them but
  1616. X      beware that CM expects the EXACT format they get saved in. Type
  1617. X      one out and see!
  1618. X
  1619. X      Selecting this item pops up a simple file requestor asking
  1620. X      for the name.
  1621. X
  1622. X
  1623. XSaveData
  1624. X    - This allows you to save a setup. It's a good idea to
  1625. X      save an experiment BEFORE you run it. That way you can
  1626. X      reload it to modify the initial parameters.
  1627. X
  1628. X      Selecting this item pops up a simple file requestor asking
  1629. X      for the name.
  1630. X
  1631. XSaveScreen
  1632. X    - This item will dump the current screen to an IFF ILBM
  1633. X      file (for use with DPaint or whatever). CM uses a hires
  1634. X      interlaced, 8 color custom screen.
  1635. X
  1636. X      This menu item is currently not implemented. If anyone is
  1637. X      interested I will put it in. Actually I'll do it sometime
  1638. X      anyway just to learn how!
  1639. X
  1640. XEXIT    - Exits CM. The window close gadget does the same thing.
  1641. X
  1642. X
  1643. X
  1644. XThe EDIT menu has the following items.
  1645. X
  1646. XSetup    - This pops up a requestor to allow you to set all the
  1647. X      simulation parameters. The parameters are described
  1648. X      below.
  1649. X
  1650. XCreate    - This puts CM into the Create Body mode. Once selected
  1651. X      a small window will open at the top of the screen showing
  1652. X      the current mouse coordinates (properly scaled). When the
  1653. X      mouse is where you want a body, click the left button.
  1654. X      A body requestor will pop up to let you fill in the
  1655. X      information for that body. The body requestor is described
  1656. X      below. You can create up to 10 bodys.
  1657. X
  1658. XModify    - Once you've created bodys (or loaded them in from a file)
  1659. X      you can step through them to view/modify their parameters.
  1660. X      You can also delete a body this way.
  1661. X
  1662. XClearScreen
  1663. X    - Just clears the screen. Useful when trails have
  1664. X      cluttered the display.
  1665. X
  1666. XClearBodys
  1667. X    - Clears all body information. A requestor will ask you if
  1668. X      you really want to do this.
  1669. X
  1670. X
  1671. XThe CONTROL menu has the following items.
  1672. X
  1673. XStart    - Starts a simulation. You must have bodys created to use
  1674. X      this item.
  1675. X
  1676. XStop    - Stops a simulation in progress. Setup info can then be
  1677. X      changed, bodys can be modified or saved and the simulation
  1678. X      restarted.
  1679. X
  1680. X
  1681. XThe setup requestor allows you to change the following.
  1682. X
  1683. XG    - The gravational constant. Entered as a floating point
  1684. X      number such as 6.67e-11.
  1685. X
  1686. XSim Time
  1687. X    - This is the time scaling for each iteration of the
  1688. X      simulation. Specified as a floating point number.
  1689. X
  1690. XReal Time
  1691. X    - Normally the simulator runs at full speed. Putting a value
  1692. X      other than zero here inserts a real delay, in miliseconds,
  1693. X      between each iteration. Maybe useful for 68020/68030 users.
  1694. X      Specified as an integer.
  1695. X
  1696. XUnits/Pixel
  1697. X    - This is the distance scale. It specifies the distance
  1698. X      between pixels. Specified as a floating point number.
  1699. X
  1700. XTrailLength
  1701. X    - This decides how a bodys trail is dealt with.
  1702. X      A value of ZERO means leave no trail.
  1703. X      A value of -1 means leave an infinite trail.
  1704. X      A value between 1 and 300 specifies the number of
  1705. X        past locations to save. This creates worm like
  1706. X        trails behind a body.
  1707. X
  1708. XShowTime
  1709. X    - If YES, the integer number of iterations will be displayed
  1710. X      during the simulation. This number can then be multiplied
  1711. X      by the time scale for real time. In some cases, such as
  1712. X      with the SVEM and SMVEM examples, it can be read directly
  1713. X      as days.
  1714. X
  1715. X
  1716. XThe Body requestor allows you to specify the following
  1717. Xcharacteristics of a body.
  1718. X
  1719. XNAME    - This is a name you give it (such as SUN, EARTH etc.)
  1720. X
  1721. X
  1722. XMASS    - This is it's mass. Entered as a floating point number.
  1723. X      The units you use should be consistant with the rest
  1724. X      of the setup information (i.e. G, scaling, velocity etc)
  1725. X
  1726. XVELOCITY
  1727. X    - The scalar velocity of the body. Floating point. Should
  1728. X      be dimensionally consistant with the rest of the setup
  1729. X      info.
  1730. X
  1731. XDIRECTION
  1732. X    - The angle of the velocity in degrees. 0 degrees is due
  1733. X      east with 90 strait up, 180 due west and 270 due south.
  1734. X      Integer number.
  1735. X
  1736. XCOLOR    - Clicking on a color will set the bodys color.
  1737. X
  1738. X
  1739. XFIXED    - YES means the body can't move. While this is not "real",
  1740. X      it can be useful for experimentation.
  1741. X
  1742. X
  1743. XThe bodys current location is displayed below the FIXED gadget.
  1744. X
  1745. X
  1746. XIn both the SETUP and the BODY requestors, clicking on OK accepts
  1747. Xthe values, RESET sets them to their defaults and CANCEL quits the
  1748. Xoperation without any changes. In addition the BODY requestor will
  1749. Xdisplay DELETE in place of CANCEL during a MODIFY operation.
  1750. XSelcecting this will delete the body from the simulation.
  1751. X
  1752. X
  1753. X
  1754. X
  1755. X
  1756. X
  1757. X
  1758. X
  1759. X
  1760. X
  1761. SHAR_EOF
  1762. echo "End of archive 1 (of 2)"
  1763. # if you want to concatenate archives, remove anything after this line
  1764. exit
  1765.